import { useState, useEffect, useRef, useImperativeHandle, forwardRef } from "react";
import { Badge, Button, Input, Select, Checkbox, message, Modal, Popover, notification } from "antd";
import SubTitle from "@/pages/OrderModule/common/components/SubTitle";
import Iconfont from "@/components/IconFont";
import SetPrintModal from "./SetPrintModal.jsx";
import VoiceSettingsModal from "./VoiceSettingsModal.jsx";
import PatchworkInvoice from "./PatchworkInvoice.jsx";
import SetExpressModal from "./SetExpressModal/index.jsx";
import DeliverOrderModal from "./DeliverOrderModal.jsx";
import {
	scanUniqueCodeOrSkuCodeOutboundorder,
	forceOutboundorder,
	queryDefaultTemplate,
	queryExpressList,
	openOrderDelivery,
	getWarehouseListOp,
	getSortingDoneNum,
	savePrinterName,
	getExpressScanConfigList,
	getUniqueCodeByCode,
	scanUniqueCodeCancelledInfoQuery
} from "../service.js";
import usePrint from "@/views/hooks/usePrint";
import { printCard } from "./print.jsx";
import { kuaiXiaoPrintFunc } from "@/utils/print.jsx";
import { usePrintExpress } from "@/views/hooks/usePrintExpress";
// 语音播报
import { speak } from "@/utils/utils.jsx";
import Api from "@/pages/OrderModule/orderList/components/Actions/service";
import Style from "../index.module.less";
import { printKmUniqcode } from '@/utils/printKm.js';
import { getKuaiMaiPrint } from '../service.js';
import { find } from 'lodash';

const OperaCard = forwardRef(({ data, setData }, ref) => {
	const [loading, setLoading] = useState(false);
	const [visible, setVisible] = useState();
	const [scanInputValue, setScanInputValue] = useState();

	const { printOptions, setPrinterName, getPrinterName, getExpressRelativePrinter, setExpressRelativePrinter } = usePrint();
	// 合格证打印模板
	const [certificateTemplateData, setCertificateTemplateData] = useState({});
	// 面单模版数据
	// const [orderTemplateData, setOrderTemplateData] = useState({});
	const [printName, setPrintName] = useState();
	// 打印商品合格证按钮
	const [isPrint, setIsPrint] = useState(false);
	// 多件是否打印
	const [isConsignment, setIsConsignment] = useState(false);
	//下拉快递列表
	const [expressList, setExpressList] = useState([]);

	//连续打印逻辑储存当前唯一码关联的所有唯一码
	const [currentCode, setCurrentCode] = useState([]);

	//面单连续打印配置
	const [scanConfig, setScanConfig] = useState({});

	// 当前打印的面单数据列表
	// const [orderList, setOrderList] = useState([]);
	// 扫描输入框
	const RefScanInput = useRef(null);
	const mainWarehould = useRef(0);

	const [warehouseList, setWarehouseList] = useState([]);
	const [waitList, setWaitList] = useState([]);

	//获取仓库列表
	const getWarehouseList = async () => {
		const { data, success } = await getWarehouseListOp();
		if (success && data?.length) {
			const obj = data.filter(v => v.isDefault == 0 && v.kind == 1);
			mainWarehould.current = obj[0]?.id;
			getWaitList();
			setWarehouseList(data);
		}
	};

	const getWaitList = async () => {
		const response = await getSortingDoneNum({ warehouseId: mainWarehould.current });
		if (response.success) {
			setWaitList(response.data);
		}
	};

	const { printExpress } = usePrintExpress({
		callback: data => { }
	});

	//校验当前是否连续打印并且打印完成
	const checkIsAll = async (val) => {
		//当前验证码集合是否包含当前验证码
		const isSame = currentCode.filter(v => v.code == val).length > 0;
		if(currentCode.length == 0 || !isSame) {
			START_LOADING();
			const { success, data } = await getUniqueCodeByCode({
				code: val
			})
			END_LOADING();
			if(success && data.length > 0) {
					const arr = data.map(v => {
					if(v.code == val) {
						return {
							code: v.code,
							sort: true
						}
					}
					return {
						code: v.code,
						sort: false
					}
					})
					setCurrentCode(arr);
					return arr.filter(v => v.sort == false).length > 0 ? false : true;
			} else {
				return false;
			}
		} else {
			const arr = [ ...currentCode ];
			find(arr, ['code', val]).sort = true;
			setCurrentCode(arr);
			return arr.filter(v => v.sort == false).length > 0 ? false : true;
		}
	}

	// 扫描回车事件
	async function commonPressEnter(v) {
		const oldOutboundNo = data.outboundNo;
		// setData(mock);
		// certificatePrint(mock);
		if (isPrint && !printName) {
			Modal.info({ centered: true, content: "打印失败，请先配置合格证打印机" });
			return;
		}
		// 判断是否有快递信息;
		if (expressList.length === 0) {
			Modal.info({ centered: true, content: "未获取快递信息" });
			return;
		}
		let value = v.replace(/\s/g, "");
		setScanInputValue(value);
		if (value) {
		const result = await scanUniqueCodeCancelledInfoQuery({ code: value });
		if (result.success) {
			if(result.data?.outboundDiscard) {
				const { code, discardReason, systemNo } = result.data;
				return notification.warning({
					icon: <Iconfont type="iconjingshi" />,
					message: (
						<span className="common-color13">
							商品“{code}”关联销售出库单已作废
							{discardReason == 1 ? <span className="common-color9">（退款商品）</span> : discardReason == 2 ? '（非退款商品）' : ''}
						</span>
					),
					description: `作废原因：订单“${systemNo}”${discardReason == 3 ? '信息变更' : '退款中'}`,
					duration: 5,
				})
			} 
		} else {
			setScanInputValue();
			return;
		}
		//如果开启了连续打印,传递是否需要发货的标识
		const isContinuous = scanConfig.configStatus == 'open' ? await checkIsAll(value) : true;
		orderAndShip({
			code: scanInputValue,
			isPrint,
			isConsignment,
			isContinuous,
			print: printName
		})
			.then(res => {
				const { data, success, code, msg } = res;
				//是否是第一次扫描
				const isFirst = data.outboundNo == oldOutboundNo ? false : true;
				if (success) {
					const batchSpeak = (data, count) => {
						if(data[count]) {
							speak({ text: data[count]}, () => batchSpeak(data, count));
							count = count + 1;
						}
					}
					const arr = isFirst ? [ ...data.orderMsgList, data.voiceTitle ] : [data.voiceTitle];
					batchSpeak(arr, 0);
					setData(data);
					// 分拣成功判断是否需要打印合格证
					if (isPrint) {
						// 打印合格证
						certificatePrint([scanInputValue], printName);
					}
					// 判断是否分拣完成
					if (!data?.noSortingNum) {
						// 当商品全部分拣完成后，需要将对应的商品订单做发货处理，
						// 直接打印面单并发货,发货成功后展示右上角角标。
						// 此时扫新的唯一码页面查询新的数据订单
						console.log("打印面单");
						/** 1.打印面单 **/
						if ((data.order?.uniqueCodeNum == 1 || isConsignment) && isContinuous) {
							PrintWaybill(data.order);
						} else {
							getWaitList();
						}
					}
					setScanInputValue();
					RefScanInput.current.focus();
				} else {
					//扫描失败的话重置数据
					if(currentCode.length > 0) {
						setCurrentCode([]);
					}
				}

				// 扫描失败，直接报返回的错误信息
				if (code === 400) {
					// console.log("data", data);
					console.log("msg", msg);
					speak({ text: msg });
					resetScanTask();
				}
			})
			.catch(err => {
				console.log(err);
				resetScanTask();
			});
			// 	// 1. 判断唯一码在erp是否存在，
			// 	// 否: 提示：唯一码不存在，请重新扫描
			// 	// 是: 判断所属订单是否作废
			// 	// 是: 提示：该商品订单不存在或已作废，请重新扫描
			// 	// 2. 若唯一码已经扫描过这里需要判断订单是否发货
			// 	// 若没有发货则展示对应的分拣记录内容
			// 	// 若已经发货则 提示:该唯一码已发货
			// 	// 若唯一码扫描后如果订单还未获取到运单号，则提示分拣失败，页面
			// 	// 提示：当前订单还未获取到运单号，
			// 	// 暂不支持分拣，弹窗T2，点击确定页面刷新，对应的商品分拣不做记录
			// 	// 3.再判断商品是否是多件
			// 	// 单件：单件的话则直接发货成功，无需分配分拣框
			// 	// 多件：判断该唯一码所属订单之前是否有占用分拣框（包括预占用和已占用）
			// 	// 是：如主图显示，并且分拣框显示占用的分拣框
			// 	// 否：按照分拣框分配逻辑判断
			// 	// 是否有可占用的分拣框
			// 	// 否：否的话则提示：分拣框不足，请等待闲置的分拣框后再分拣
			// 	// 是：分配新的分拣框和占用，分拣成功，
		} else {
			Modal.info({ centered: true, title: "提示", content: "未检测到扫描单号" });
			resetScanTask();
		}
	}

	//获取面单信息并打印
	const handlePrint = async (systemNos, printer) => {
		setLoading(true);
		const { data, success } = await Api.getPrintDataOp({ systemNos, printPageType: 2 });
		setLoading(false);
		if (success) {
			if (!data?.length) {
				return message.info("暂未获取到打印数据。");
			}
			const companyObj = data[0]?.items?.[0] || {},
				obj = companyObj?.printLogisticsList?.[0] || {};

			//保存打印机标识
			const arr = [
				{
					printerName: printer,
					taskId: companyObj.printTaskId
				}
			];
			savePrinterName(arr);
			kuaiXiaoPrintFunc({ ...obj, printer, printTaskId: companyObj.printTaskId }, res => {
				visible && setVisible(false);
				const { status, printTaskId, orderSn } = res;
				if (status) {
					Api.printSuccessOp({
						printTaskId,
						systemNos: [orderSn],
						logPage: 21
					});
				}
			});
		}
	};

	// 分拣完成,打印面单
	const PrintWaybill = order => {
		console.log('order')
		if (!order) {
			console.error("PrintWaybill 方法 order 为空");
			return;
		}
		const printConfig = getExpressRelativePrinter() || {};
		if (printConfig[order?.expressCompany]) {
			if (order.outboundNo) {
				// printExpress([order.outboundNo]);
				handlePrint([order.systemNo], printConfig[order?.expressCompany]);
			} else {
				Modal.info({ centered: true, title: "提示", content: "未获取出库单号，打印失败" });
			}
		} else {
			Modal.info({
				centered: true,
				title: "提示",
				content: `打印失败，${order?.expressCompany}未设置打印机`
			});
		}
	};

	// 重置(F1)
	function resetScanTask() {
		setScanInputValue();
		setData({});
		getWaitList();
		RefScanInput.current.focus();
	}
	function handlePrinterName(name) {
		setPrintName(name);
		// setPrinterName(name);
	}
	// 拆单发货(F5)
	function splitOrder() {
		// 只对部分分拣的订单有效，所以分拣完成或者未分拣时，按钮置灰不显示
		// message.info("拆单发货");
		if(Object.keys(data).length == 0) {
			return;
		}
		if (isPrint && !printName) {
			Modal.info({ centered: true, content: "打印失败，请先配置合格证打印机" });
			return;
		}
		// 判断是否有快递信息;
		if (expressList.length === 0) {
			Modal.info({ centered: true, content: "未获取快递信息" });
			return;
		}
		const { systemNo } = data.order;
		openOrderDelivery({ systemNo }).then(res => {
			const { success, data, msg } = res;
			if (success) {
				setData(data.resultMap);
				message.success(msg);
				PrintWaybill(data?.printList[0]);
			}
		});
	}
	// 强制发货(F12)
	function forceOrder() {
		// 有订单数据时按钮可以点击操作
		// 点击后将对应订单下的商品直接进行发货处理，此时没有扫描唯一码的商品可以直接跳过处理，
		// 直接将订单状态更改为已发货，对应的商品唯一码状态也更改为已发货；
		// 但是对应日志也需要同样做记录，记录为2条：分拣、发货
		if (data?.order?.outboundNo) {
			forceOutboundorder({
				outboundNos: [data.order.outboundNo],
				isPrint,
				force: true,
				print: printName,
				deliveryScenario: 3
			}).then(res => {
				const { success, data: newData } = res;
				if (success) {
					setData({
						...data,
						sendStatus: true
					})
					message.success("发货成功");
					/** 1.打印面单 **/
					const { printList } = newData;
					const obj = printList[0];
					if(!obj) {
						return;
					}
					const printConfig = getExpressRelativePrinter() || {};
					if (printConfig[obj?.expressCompany]) {
						if (obj.outboundNo) {
							// printExpress([order.outboundNo]);
							handlePrint([obj.systemNo], printConfig[obj?.expressCompany]);
						} else {
							Modal.info({ centered: true, title: "提示", content: "未获取出库单号，打印失败" });
						}
					} else {
						Modal.info({
							centered: true,
							title: "提示",
							content: `打印失败，${obj?.expressCompany}未设置打印机`
						});
					}
				}
			});
			setScanInputValue();
			RefScanInput.current.focus();
		}
	}
	// 补打面单(F4)
	function supplyOrder() {
		// 点击出弹窗进行输入对应需要补打的订单中所包含的唯一码
		// 扫描唯一码后需要判断
		// 当扫的唯一码已经有面单存在则点击补打面单进行面单打印
		// 若还未进行面单的打印
		// 则扫描后
		// 提示：该订单未打印过，请直接扫码发货
		// 点击补打面单后页面数据重置，只有在点击右上方关闭再将弹窗关闭
		// 点击则重新打面单，面单模板和原来一样
		setVisible("PatchworkInvoice");
	}
	// 打单发货接口
	async function orderAndShip(params) {
		return await scanUniqueCodeOrSkuCodeOutboundorder(params);
	}
	// 打印合格证
	async function certificatePrint(codes, printer) {
		const { success, data } = await getKuaiMaiPrint({
			codes,
			labelType: 7
		})
		if(success && data) {
			// 开始打印合格证
			printKmUniqcode(JSON.parse(data), printer, () => {
				// console.log("打印合格证回调");
			});
		}
	}
	// 获取合格证默认模板
	const getDefaultTemplate = async () => {
		setLoading(true);
		const { success, data = {} } = await queryDefaultTemplate();
		console.log("获取合格证模板", data);
		if (success) {
			setCertificateTemplateData(data);
		}
		setLoading(false);
	};

	//获取快递列表
	const getExpressList = async () => {
		const { success, data } = await queryExpressList({
			type: 0 // 可用快递列表 0:自发可用，1:全部可用
		});
		if (success) {
			setExpressList(data);
		} else {
			expressList?.length && setExpressList([]);
		}
	};

	//获取面单打印配置
	const getScanConfigData = async () => {
		const { success, data } = await getExpressScanConfigList();
		if(success) {
			const obj = data[0] || {};
			setScanConfig(obj);
		}
	}

	// 阻止默认事件
	const prevent = e => {
		if (window.location.hash == "#/views/StockManage/InvoiceDelivery") {
			if (["Enter", "F5", "F12", "F4", "F1"].includes(e.key)) e.preventDefault();
		}
	};
	// 键盘事件监听
	const scanRequest = e => {
		if (window.location.hash == "#/views/StockManage/InvoiceDelivery") {
			const { key } = e;
			switch (key) {
				// case "Enter":
				// 	// 触发扫描请求
				// 	message.info("触发扫描请求", e);
				// 	break;
				case "F1":
					// 重置(F1)
					resetScanTask();
					break;
				case "F4":
					// 补打面单(F4)
					supplyOrder();
					break;
				case "F5":
					splitOrder();
					// 拆单发货(F5)
					break;
				case "F12":
					forceOrder();
					// 强制发货(F12);
					break;
				default:
					break;
			}
		}
	};
	// 获取合格证打印模板
	useEffect(() => {
		if (JSON.stringify(certificateTemplateData) === "{}") getDefaultTemplate();
	}, [isPrint]);
	//监听键盘事件,阻止默认事件
	useEffect(() => {
		window.addEventListener("keydown", prevent, false);
		window.addEventListener("keyup", scanRequest, false);
		return () => {
			window.removeEventListener("keydown", prevent, false);
			window.removeEventListener("keyup", scanRequest, false);
		};
	});

	useEffect(() => {
		RefScanInput.current.focus();
		// 获取快递列表
		getExpressList();
		getWarehouseList();
		getScanConfigData();
	}, []);

	useEffect(() => {
		// 打印机只能修改不能置空，没有设置过打印机则展示为默认的打印机，若默认打印机都没有获取到则进入页面提示，在对应需要打印合格证时需要弹窗提示T4，需要打印快递面单时提示T3
		if (expressList.length) {
			if (printOptions.length) {
				const Options = expressList.map((item, index) => { });
				const printConfig = getExpressRelativePrinter() || {};
				expressList.forEach(item => {
					// 没有设置过打印机则展示为默认的打印机
					if (!printConfig[item.baseExpressName]) printConfig[item.baseExpressName] = printOptions[0].key;
					if (!printConfig[item.name]) printConfig[item.name] = printOptions[0].key;
				});
				setExpressRelativePrinter(printConfig);
			}
		}
	}, [expressList]);

	useImperativeHandle(ref, () => ({
		resetScanTask
	}));

	const onCancel = () => {
		setVisible("");
	};

	const DeliverOrderModalProps = {
		warehouseList,
		mainWarehould: mainWarehould.current,
		handlePrint(arr) {
			if (arr?.length) {
				printExpress(arr, 2);
			}
		},
		handleOk() {
			getWaitList();
			setVisible(false);
		},
		handleCancel() {
			setVisible(false);
		}
	};

	return (
		<div className={Style.card}>
			{/* <Alert
				showIcon
				type="info"
				message={
					<>
						<span>注： 1、分拣完成自动打印快递单并发货</span>
						<br />
						<span>2、若订单没有获取物流单号则打印会跳过处理</span>
					</>
				}
				style={{ marginBottom: "16px" }}
			/> */}
			<div className="flex justify-between" style={{ marginBottom: "16px" }}>
				<Input
					ref={RefScanInput}
					value={scanInputValue}
					onChange={e => {
						setScanInputValue(e.target.value.replace(/\s/g, ""));
					}}
					onPressEnter={e => commonPressEnter(e.target.value)}
					placeholder="请扫描/输入商品唯一码"
					autoComplete="off"
					style={{
						width: "476px",
						height: "40px"
					}}
				/>
				<Button
					style={{
						width: "72px",
						height: "40px"
					}}
					onClick={() => resetScanTask()}
				>
					重置(F1)
				</Button>
			</div>

			<div className="flex justify-between" style={{ marginBottom: "16px" }}>
				<SubTitle title="打印设置" as="s2" symbol />
				<div>
					<Button
						type="link"
						onClick={() => setVisible("VoiceSettingsModal")}
						icon={<Iconfont type="iconbobao" style={{ fontSize: 14 }} />}
					>
						语音播报设置
					</Button>
					<Button
						type="link"
						onClick={() => setVisible("SetPrintModal")}
						icon={<Iconfont type="icona-lujing111" style={{ fontSize: 14 }} />}
					>
						快递面单打印机配置
					</Button>
				</div>
			</div>
			<div>
				<Checkbox value={isPrint} onChange={e => setIsPrint(e.target.checked)} style={{ marginBottom: "16px" }}>
					<span className={Style.font16}>打印商品合格证</span>
				</Checkbox>
				<Select value={printName} placeholder="请选择打印机" onChange={handlePrinterName} className={Style.printSelect}>
					{printOptions}
				</Select>
			</div>
			<div style={{ marginBottom: "4px", display: "flex", justifyContent: "space-between" }}>
				<Checkbox value={isConsignment} onChange={e => setIsConsignment(e.target.checked)} style={{ marginBottom: "16px" }}>
					<span className={Style.font16}>分拣完成后自动打单并发货（多件）</span>
				</Checkbox>
				<Badge count={waitList?.length}>
					<Button type="link" onClick={() => setVisible("DeliveryModal")}>
						发货已配齐订单
					</Button>
				</Badge>
			</div>
			<div className="flex justify-between">
				<Button
					disabled={data?.sendStatus || !(data?.sortingTableList?.length && data?.noSortingTableList?.length)}
					onClick={() => {
						splitOrder();
					}}
					style={{ height: 40, width: 120 }}
				>
					拆单发货(F5)
				</Button>
				<Popover content={
					<div>
						<div>强制发货：未拿货商品转库存发货（不收取备货金额）</div>
						<div>注意：转库存商品只针对<span className="common-color9">待拿货</span>的商品，若商品已经APP备货则不可转库存</div>
					</div>
				}>
				<Button
					disabled={!data?.order || data?.sendStatus}
					onClick={() => {
						forceOrder();
					}}
					style={{ height: 40, width: 120 }}
				>
					强制发货(F12)
				</Button>
				</Popover>
				<Button
					onClick={() => {
						supplyOrder();
					}}
					style={{ height: 40, width: 120 }}
				>
					补打面单(F4)
				</Button>
				<Button
					disabled={!data?.order?.outboundNo || data?.sendStatus}
					onClick={() => {
						setVisible("SetExpressModal");
					}}
					style={{ height: 40, width: 120 }}
				>
					修改快递
				</Button>
			</div>
			{visible === "SetPrintModal" && (
				<SetPrintModal expressList={expressList} scanConfig={scanConfig} setExpressList={setExpressList} handleOk={val => setScanConfig(val)} onCancel={onCancel} />
			)}
			{visible === "VoiceSettingsModal" && <VoiceSettingsModal onCancel={onCancel} />}
			{visible === "PatchworkInvoice" && <PatchworkInvoice setData={setData} onCancel={onCancel} handlePrint={handlePrint} />}
			{visible === "SetExpressModal" && <SetExpressModal data={data} setData={setData} onCancel={onCancel} />}
			{visible === "DeliveryModal" && <DeliverOrderModal {...DeliverOrderModalProps} />}
		</div>
	);
});
export default OperaCard;
